import datetime
import threading

import pymongo
import redis

from wbot import settings


class Cache:
    _lock = threading.Lock()

    def __init__(self):
        self.config = settings.CACHE
        self.pool = redis.ConnectionPool(**self.config)

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with cls._lock:
                if not hasattr(cls, '_instance'):
                    cls._instance = super().__new__(cls)

        return cls._instance

    def set(self, name, value):
        r = redis.Redis(connection_pool=self.pool)
        r.set(name, value)
        r.expire(name, 120)  # 消息撤回时间2分钟内

    def get(self, name):
        r = redis.Redis(connection_pool=self.pool)
        res = r.get(name)
        return res

    def get_str(self, name):
        r = redis.Redis(connection_pool=self.pool)
        res = r.get(name)
        if res:
            return res.decode('utf8')
        else:
            return None

    def hset(self, field, mapping):
        r = redis.Redis(connection_pool=self.pool)
        r.hmset(field, mapping)
        r.expire(field, 3600)  # 好友缓存一小时

    def hget(self, field, mapping):
        r = redis.Redis(connection_pool=self.pool)
        res = r.hget(field, mapping)
        return res.decode('utf8')


class MongoClient:
    client = pymongo.MongoClient()

    @classmethod
    def save_message(cls, msg: dict):
        db = cls.client.wechat
        db.message.insert(msg)

    @classmethod
    def save_friend(cls, friend):
        db = cls.client.wechat
        friend.update({'insert_time': datetime.datetime.now()})
        db.friend.insert(friend)

    @classmethod
    def save_room_members(cls, member):
        db = cls.client.wechat
        member.update({'insert_time': datetime.datetime.now()})
        db.room.insert(member)

    @classmethod
    def get_monitor_room(cls) -> list:
        """获取需要监控的群聊名称"""
        db = cls.client.wechat
        cursor = db['monitor-room'].find()
        res = [room['name'] for room in cursor]
        return res

    @classmethod
    def get_blocked_room(cls) -> list:
        """获取不需要处理的群消息"""
        db = cls.client.wechat
        cursor = db['blocked-room'].find()
        res = [room['name'] for room in cursor]
        return res
